package com.harmontronics.app.pedestal.agent;

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.Uri;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.TypedValue;
import android.view.KeyEvent;
import android.view.View;
import android.webkit.WebResourceRequest;
import android.webkit.WebResourceResponse;
import android.webkit.WebView;
import android.widget.FrameLayout;
import android.widget.TextView;

import androidx.activity.result.ActivityResult;
import androidx.activity.result.ActivityResultCallback;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;

import com.blankj.utilcode.util.FileUtils;
import com.blankj.utilcode.util.LogUtils;
import com.harmontronics.app.pedestal.AppConstants;
import com.harmontronics.app.pedestal.R;
import com.harmontronics.app.pedestal.ScanActivity;
import com.harmontronics.app.pedestal.bridge.AppBridge;
import com.harmontronics.app.pedestal.bridge.AudioBridge;
import com.harmontronics.app.pedestal.bridge.BMapBridge;
import com.harmontronics.app.pedestal.bridge.CameraBridge;
import com.harmontronics.app.pedestal.bridge.FileBridge;
import com.harmontronics.app.pedestal.bridge.GpsBridge;
import com.harmontronics.app.pedestal.bridge.ImageBridge;
import com.harmontronics.app.pedestal.bridge.MqttBridge;
import com.harmontronics.app.pedestal.bridge.NativeBridge;
import com.harmontronics.app.pedestal.bridge.NotifyBridge;
import com.harmontronics.app.pedestal.bridge.SqliteBridge;
import com.harmontronics.app.pedestal.bridge.VideoBridge;
import com.harmontronics.app.pedestal.bridge.WebViewBridge;
import com.harmontronics.app.pedestal.bridge.model.BridgeCallback;
import com.harmontronics.app.pedestal.bridge.model.BridgeChooseResult;
import com.harmontronics.app.pedestal.bridge.model.BridgeFile;
import com.harmontronics.app.pedestal.bridge.model.BridgeScanResult;
import com.huawei.hms.ml.scan.HmsScan;
import com.just.agentweb.AgentWeb;
import com.just.agentweb.WebChromeClient;
import com.just.agentweb.WebViewClient;
import com.leon.lfilepickerlibrary.LFilePicker;
import com.leon.lfilepickerlibrary.utils.Constant;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import wendu.dsbridge.DWebView;
import wendu.dsbridge.OnReturnValue;

public class WebActivity extends AppCompatActivity {

    protected AgentWeb mAgentWeb;
    private FrameLayout mContainer;
    private FrameLayout mToolbar;
    private TextView mTitleTextView;

    private LFilePicker mFilePicker;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        LogUtils.d("WebActivity onCreate");
        setContentView(R.layout.activity_web);

        mContainer = this.findViewById(R.id.web_container);
        mToolbar = this.findViewById(R.id.toolbar);
        mTitleTextView = this.findViewById(R.id.toolbar_title);
        this.findViewById(R.id.toolbar_back).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                finish();
            }
        });

        DWebView webView = new DWebView(this);
        DWebView.setWebContentsDebuggingEnabled(true);
        webView.getSettings().setAllowFileAccess(true);
        webView.getSettings().setAllowContentAccess(true);
        webView.getSettings().setBlockNetworkImage(false);
        webView.getSettings().setBlockNetworkLoads(false);
        webView.getSettings().setAllowFileAccessFromFileURLs(true);
        webView.getSettings().setAllowUniversalAccessFromFileURLs(true);
        webView.getSettings().setAppCacheEnabled(true);
        webView.addJavascriptObject(new AppBridge(), "APP");
        webView.addJavascriptObject(new AudioBridge(), "AUDIO");
        webView.addJavascriptObject(new CameraBridge(this), "CAMERA");
        webView.addJavascriptObject(new FileBridge(this), "FILE");
        webView.addJavascriptObject(new ImageBridge(), "IMAGE");
        webView.addJavascriptObject(new MqttBridge(this), "MQTT");
        webView.addJavascriptObject(new NativeBridge(this), "NATIVE");
        webView.addJavascriptObject(new NotifyBridge(), "NOTIFY");
        webView.addJavascriptObject(new SqliteBridge(), "SQLITE");
        webView.addJavascriptObject(new VideoBridge(), "VIDEO");
        webView.addJavascriptObject(new WebViewBridge(this), "WEBVIEW");
        webView.addJavascriptObject(new GpsBridge(this), "GPS");
        webView.addJavascriptObject(new BMapBridge(this), "BMAP");
        webView.setWebViewClient(new WebViewClient() {
            @Override
            public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
                return super.shouldInterceptRequest(view, request);
            }

            @Override
            public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
                String key = "http://localhost/";
                WebResourceResponse response = null;
                if (url.contains(key)) {
                    try {
                        String imgPath = url.replace(key, "");
                        imgPath = Uri.parse(imgPath).getPath();
                        InputStream localCopy = new FileInputStream(imgPath);
                        //当前只针对图片
                        response = new WebResourceResponse("image/*", "UTF-8", localCopy);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                return response;
            }
        });

        mAgentWeb = AgentWeb.with(this)
                .setAgentWebParent(mContainer, new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT))
                .useDefaultIndicator()
                .setWebChromeClient(mWebChromeClient)
                .setWebView(webView)
                .setMainFrameErrorView(R.layout.agentweb_error_page, -1)
                .setSecurityType(AgentWeb.SecurityType.STRICT_CHECK)
                .interceptUnkownUrl() //拦截找不到相关页面的Scheme
                .createAgentWeb()
                .ready()
                .go(getUrl());

        IntentFilter filter = new IntentFilter();
        filter.addAction("NotifyClick");
        registerReceiver(new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                String title = intent.getStringExtra("title");
                String content = intent.getStringExtra("content");
                onNotifyClick(title, content);
            }
        }, filter);
    }

    public void onNotifyClick(String title, String content) {
        LogUtils.d("onNotifyClick");
        ((DWebView) mAgentWeb.getWebCreator().getWebView()).callHandler("NOTIFY.onClick", new String[]{title, content},
                new OnReturnValue<Object>() {
                    @Override
                    public void onValue(Object retValue) {
                    }
                });
    }

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        LogUtils.d("WebActivity onNewIntent");
        mAgentWeb.getWebCreator().getWebView().loadUrl(getUrl());
    }

    private WebChromeClient mWebChromeClient = new WebChromeClient() {
        @Override
        public void onReceivedTitle(WebView view, String title) {
            super.onReceivedTitle(view, title);
            if (mTitleTextView != null) {
                mTitleTextView.setText(title);
            }
        }
    };

    public String getUrl() {
        if (null != getIntent() &&
                null != getIntent().getStringExtra("url") &&
                !TextUtils.isEmpty(getIntent().getStringExtra("url"))) {
            String url = getIntent().getStringExtra("url");
            if (url.startsWith("http")) {
                return url;
            }

            LogUtils.d(url);
            String localUrl = "file://" + AppConstants.DOWNLOAD_HTML_FOLDER + getIntent().getStringExtra("url");
            LogUtils.d(localUrl);

            return localUrl;
        }
        return "file://" + AppConstants.START_H5_PATH;
    }

    /**
     * // namespace test for syn functions
     * dsBridge.register("WEBVIEW", {
     * tag: "WEBVIEW",
     * onBackIntercept: function () {
     * return true;
     * }
     * })
     *
     * @param keyCode
     * @param event
     * @return
     */
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
            LogUtils.d("WebActivity onKeyDown -> KEYCODE_BACK");
            ((DWebView) mAgentWeb.getWebCreator().getWebView()).callHandler("WEBVIEW.onBackIntercept", new OnReturnValue<Boolean>() {
                @Override
                public void onValue(Boolean retValue) {
                    LogUtils.d("retValue: " + retValue);
                    if (!retValue) {
                        finish();
                    }
                }
            });
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }

    @Override
    protected void onPause() {
        mAgentWeb.getWebLifeCycle().onPause();
        super.onPause();
    }

    @Override
    protected void onResume() {
        mAgentWeb.getWebLifeCycle().onResume();
        super.onResume();
        ((DWebView) mAgentWeb.getWebCreator().getWebView()).callHandler("WEBVIEW.onShow", new OnReturnValue<Object>() {
            @Override
            public void onValue(Object retValue) {
            }
        });
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mAgentWeb.getWebLifeCycle().onDestroy();
    }

    private ActivityResultLauncher<Intent> mScanCodeLauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(),
            new ActivityResultCallback<ActivityResult>() {
                @Override
                public void onActivityResult(ActivityResult result) {
                    if (result.getResultCode() == Activity.RESULT_OK) {
                        String text = result.getData().getStringExtra("text");
                        int type = result.getData().getIntExtra("type", HmsScan.QRCODE_SCAN_TYPE);

                        String scanType = type == HmsScan.QRCODE_SCAN_TYPE || type == HmsScan.DATAMATRIX_SCAN_TYPE || type == HmsScan.AZTEC_SCAN_TYPE ? "qrCode" : "barCode";

                        mScanCodeCallback.onSuccess(new BridgeScanResult(text, scanType));
                    } else if (result.getResultCode() == Activity.RESULT_CANCELED) {
                        mScanCodeCallback.onFail("CANCELED");
                    } else {
                        mScanCodeCallback.onFail("FAILED");
                    }
                }
            });

    private BridgeCallback mScanCodeCallback;

    public void scanCode(boolean isShowAlbum, int scanCode, BridgeCallback callback) {
        mScanCodeCallback = callback;
        Intent intent = new Intent(this, ScanActivity.class);
        intent.putExtra(ScanActivity.ARGS_SHOW_ALBUM, isShowAlbum);
        intent.putExtra(ScanActivity.ARGS_SCAN_MODE, scanCode);
        mScanCodeLauncher.launch(intent);
    }

    public void replace(String path) {
        mAgentWeb.getWebCreator().getWebView().loadUrl("file://" + AppConstants.DOWNLOAD_HTML_FOLDER + path);
    }

    public void openStart() {
        mAgentWeb.getWebCreator().getWebView().loadUrl("file://" + AppConstants.START_H5_PATH);
    }

    private BridgeCallback mFileChooseCallback;

    public void fileChoose(int count, String[] patterns, BridgeCallback callback) {
        mFileChooseCallback = callback;

        if (null == mFilePicker) {
            mFilePicker = new LFilePicker();
        }

        new LFilePicker()
                .withActivity(this)
                .withRequestCode(100)
                .withTitle("文件选择")
                .withMutilyMode(count > 1)
                .withMaxNum(count)
                .withNotFoundBooks("至少选择一个文件")
                .withFileFilter(null != patterns ? patterns : new String[]{})
                .start();
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable @org.jetbrains.annotations.Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode != RESULT_OK && requestCode == 100) {
            if (null != mFileChooseCallback) {
                mFileChooseCallback.onFail("cancel");
            }
            return;
        }

        if (requestCode == 100) {
            List<String> filePaths = data.getStringArrayListExtra(Constant.RESULT_INFO);
            List<BridgeFile> files = new ArrayList<>();
            if (null != filePaths && !filePaths.isEmpty()) {
                for (int i = 0; i < filePaths.size(); i++) {
                    BridgeFile file = new BridgeFile(FileUtils.getFileLength(filePaths.get(i)), filePaths.get(i));
                    files.add(file);
                }
            }
            if (null != mFileChooseCallback) {
                mFileChooseCallback.onSuccess(new BridgeChooseResult(filePaths, files));
            }
        }
    }

    public void onReceive(String topic, String message) {
        ((DWebView) mAgentWeb.getWebCreator().getWebView()).callHandler("MQTT.onReceive", new String[]{topic, message},
                new OnReturnValue<Object>() {
                    @Override
                    public void onValue(Object retValue) {
                    }
                });
    }

    public void showOrHideToolbar(boolean show) {
        LogUtils.d("showOrHideToolbar" + show);
        int actionBarHeight = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 48, getResources().getDisplayMetrics());
        LogUtils.d("actionBarHeight" + actionBarHeight);
        FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT);
        layoutParams.topMargin = show ? actionBarHeight : 0;
        mContainer.setLayoutParams(layoutParams);
        mToolbar.animate().translationY(show ? 0 : -actionBarHeight);
    }
}
